package com.ashleyleung.jetpack_b_station.player

import android.os.Looper
import androidx.lifecycle.*
import com.ashleyleung.jetpack_b_station.SysApplication
import com.ashleyleung.jetpack_b_station.lifecycle.*
import timber.log.Timber

/**
 * @author lxy
 * @name
 * @class describe 数据容器
 *  可以监听数据的变化
 * @date 2022-06-22
 *
 */
class DataListenContainer<T> {
    private val blocks = arrayListOf<(T?) -> Unit>()
    private val viewLifeCycleProviders = hashMapOf<(T?) -> Unit, Lifecycle>()

    var value: T? = null
        //当数据变化的时候:就通知更新
        set(value: T?) {
            field = value//这句关键。前面

            var str2 = "value " + value.toString()
//            Timber.e(str2)
            var str = "set 数量：" + blocks.size
//            Timber.e(str)
            //判断当前线程是不是主线程
            //如要是，则直接执行，否则切换到主线程再执行  确保线程UI 安全
            if (Looper.getMainLooper().thread === Thread.currentThread()) {
                //判断对应View的生命周期是什么
                blocks.forEach {
                    dispatchValue(it, value)
                }
            } else {
                SysApplication.handler.post {
                    blocks.forEach {
                        dispatchValue(it, value)
                    }
                }
            }


        }

    private fun dispatchValue(it: (T?) -> Unit, value: T?) {
        var lifecycle: Lifecycle? = viewLifeCycleProviders[it]
        if (lifecycle != null && lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
            //至少START 以上才可以更新

            Timber.e("更新UI")
            it.invoke(value)
        } else {
            Timber.e("ui不可见")
        }


    }

    /**
     * 有可能有多个view.
     * 进行监听所有owner-bLock
     *我们得管理起来
     */
    fun addListener(owner: LifecycleOwner, valueObserver: (T?) -> Unit) {

//        owner.getLifecycleProvider().addLifeListener(this)  Lesson18
        val lifecycle: Lifecycle = owner.lifecycle
        viewLifeCycleProviders[valueObserver] = lifecycle
        //当view destroy的时候，要从集合中删除
        val valueObserverWrapper = ValueObserverWrapper(valueObserver)
        lifecycle.addObserver(valueObserverWrapper)

        if (!blocks.contains(valueObserver)) {
            blocks.add(valueObserver)
            var str = "add $valueObserver"
            Timber.e(str)
        }
        var str = "数量：" + blocks.size
        Timber.e(str)
    }

    inner class ValueObserverWrapper(private val valueObserver: (T?) -> Unit) :
        LifecycleObserver {
        //通过注解方式获取,已废弃,  与MusicPresenter 直接调用onStateChanged监听对比。这个方式省事，
        @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
        fun removeValueObserver() {
            Timber.e("监听ON_DESTROY")
            //当监听到当前的View，生命周期为Destroy的时候，就把LifecycleProvider从集合中删除
            viewLifeCycleProviders.remove(valueObserver)
        }
        @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
        fun onStop(owner:LifecycleOwner,){
            Timber.e("停止onStateChanged信号变化监听")
            println("owner onStop - -->$owner")
        }
        @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
        fun onAny(owner:LifecycleOwner,event:Lifecycle.Event){
            println("owner - -->$owner")
        }

        /*对应MusicPresenter

        override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
               when(event) {
                   Lifecycle.Event.ON_CREATE -> {}
                   Lifecycle.Event.ON_START -> {
                       Timber.e("监听onStateChanged信号变化")
                   }
                   Lifecycle.Event.ON_RESUME -> {}
                   Lifecycle.Event.ON_PAUSE -> {}
                   Lifecycle.Event.ON_STOP -> {
                       Timber.e("停止onStateChanged信号变化监听")
                   }
                   Lifecycle.Event.ON_DESTROY -> {
                       Timber.e("当onStateChanged监听到当前的View，生命周期为Destroy的时候，就把LifecycleProvider从集合中删除")
                       //当监听到当前的View，生命周期为Destroy的时候，就把LifecycleProvider从集合中删除
                       viewLifeCycleProviders.remove(valueObserver)
                   }
                   Lifecycle.Event.ON_ANY -> {}
               }
           }*/


    }
}